package kernel_db.interfaces;

import java.util.List;

import common.entities.enums.*;
import common.entities.persistent.*;
import common.entities.nonpersistent.GameQuestion;
import kernel_db.db.*;

public interface IDB {

	// General
	/**
	 * closes all of the connections of the database
	 * **/
	void closeAllConnections() throws DB_Error;

	/**
	 * returns top numberOfUsers users ordered by highest win
	 * 
	 * @param numberOfUsers
	 *            - number of users to show in hall of fame
	 * **/
	List<User> hallOfFame(int numberOfUsers) throws DB_Error;

	// Manage a Game Interface
	/**
	 * returns a set of question that are suitable for a game
	 * **/
	List<GameQuestion> generateGame() throws DB_Error;

	/**
	 * updates the score of a user
	 * 
	 * @param user
	 * **/
	void updateUserScore(User user) throws DB_Error;

	// Manage user Interface
	/**
	 * checks if a user is listed in the data base
	 * 
	 * @param user
	 * **/
	User authenticateUser(User user) throws DB_Error;

	/**
	 * performs the specific action on the user
	 * 
	 * @param action
	 *            - the action to perform on the user
	 * @param user
	 * **/
	void actionUser(ACTION action, User user) throws DB_Error;

	/**
	 * returns number of users that their name is sub string of userNameSubStr
	 * 
	 * @param userNameSubStr
	 *            - substring of user name
	 * **/
	int countUsers(String userNameSubStr) throws DB_Error;

	/**
	 * returns the set of users from DB that match wanted query ordered by user
	 * name
	 * 
	 * @param userNameSubStr
	 *            - substring of user name
	 * **/
	List<User> getUsers(String userNameSubStr, int from, int to)
			throws DB_Error;

	// Manage Genre Interface
	/**
	 * performs the specific action on genre
	 * 
	 * @param action
	 *            - the action to perform on the genre
	 * @param genre
	 * **/
	void actionGenre(ACTION action, Genre genre) throws DB_Error;

	/**
	 * returns number of genres
	 * 
	 * @param GenreSubStr
	 *            - substring of genre name
	 * @param movie
	 *            - a movie the genre associated with
	 * **/
	int countGenres(String GenreSubStr, Movie movie) throws DB_Error;

	/**
	 * returns the set of genres from DB that match wanted query ordered by name
	 * 
	 * @param GenreSubStr
	 *            - substring of GenreSubStr
	 * **/
	List<Genre> getGenres(String GenreSubStr, int from, int to) throws DB_Error;

	// Manage Country Interface
	/**
	 * performs the specific action on country
	 * 
	 * @param action
	 *            - the action to perform on the country
	 * @param country
	 * **/
	void actionCountry(ACTION action, Country country) throws DB_Error;

	/**
	 * returns number of countries that match the query
	 * 
	 * @param countrySubStr
	 *            - substring of country name
	 * @param movie
	 *            - a movie the country associated with
	 * **/
	int countCountries(String countrySubStr, Movie movie) throws DB_Error;

	/**
	 * returns the set of countries from DB that match wanted query ordered by
	 * name
	 * 
	 * @param countrySubStr
	 *            - substring of countrySubStr
	 * **/
	List<Country> getCountries(String countrySubStr, int from, int to)
			throws DB_Error;

	// Manage Actor Interface
	/**
	 * performs the specific action on actor
	 * 
	 * @param action
	 *            - the action to perform on actor
	 * @param genre
	 * **/
	void actionActor(ACTION action, Actor actor) throws DB_Error;

	/**
	 * returns number of actors that match the query
	 * 
	 * @param firstNameSubStr
	 *            - substring of first name
	 * @param lastNameSubStr
	 *            - substring of last name
	 * @param sex
	 * @param movie
	 *            - a movie the director associated with
	 * **/
	int countActors(String firstNameSubStr, String lastNameSubStr, SEX sex,
			Movie movie) throws DB_Error;

	/**
	 * returns set of actors that match the query
	 * 
	 * @param firstNameSubStr
	 *            - substring of first name
	 * @param lastNameSubStr
	 *            - substring of last name
	 * @param sex
	 * @param movie
	 *            - a movie the director associated with
	 * **/
	List<Actor> getActors(String firstNameSubStr, String lastNameSubStr,
			SEX sex, Movie movie, int from, int to) throws DB_Error;

	/**
	 * returns the set of movies that the actor played in
	 * 
	 * @param actor
	 * **/
	List<Movie> getActorMovies(Actor actor, int from, int to) throws DB_Error;

	/**
	 * deletes the connection between actor and movie
	 * 
	 * @param actor
	 * @param movie
	 * */
	void deleteMovieFromActor(Actor actor, Movie movie) throws DB_Error;

	// Manage Director Interface
	/**
	 * performs the specific action on director
	 * 
	 * @param action
	 *            - the action to perform on director
	 * @param director
	 * **/
	void actionDirector(ACTION action, Director director) throws DB_Error;

	/**
	 * returns number of directors that match the query
	 * 
	 * @param firstNameSubStr
	 *            - substring of first name
	 * @param lastNameSubStr
	 *            - substring of last name
	 * @param movie
	 *            - a movie the director associated with
	 * **/
	int countDirectors(String firstNameSubStr, String lastNameSubStr,
			Movie movie) throws DB_Error;

	/**
	 * returns set of directors that match the query
	 * 
	 * @param firstNameSubStr
	 *            - substring of first name
	 * @param lastNameSubStr
	 *            - substring of last name
	 * @param movie
	 *            - a movie the director associated with
	 * **/
	List<Director> getDirectors(String firstNameSubStr, String lastNameSubStr,
			Movie movie, int from, int to) throws DB_Error;

	/**
	 * returns the set of director's movie
	 * 
	 * @param director
	 * **/
	List<Movie> getDirectorMovies(Director director, int from, int to)
			throws DB_Error;

	/**
	 * deletes the connection between director and movie
	 * 
	 * @param director
	 * @param movie
	 * */
	void deleteMovieFromDirector(Director director, Movie movie)
			throws DB_Error;

	// Manage Movie Interface

	/**
	 * performs the specific action on movie
	 * 
	 * @param action
	 *            - the action to perform on movie
	 * @param movie
	 * **/
	void actionMovie(ACTION action, Movie movie) throws DB_Error;

	/**
	 * returns number of movies that match wanted query orderd by title
	 * 
	 * @param titleSubStr
	 *            - null if not used, otherwise some string
	 * @param releaseYearMin
	 *            - -1 if not used, otherwise a year
	 * @param releaseYearMax
	 *            - -1 if not used, otherwise a year
	 * @param rankMin
	 *            - -1.0F if not used, otherwise a rank
	 * @param rankMax
	 *            -1.0F if not used, otherwise a rank
	 * @param actor
	 *            - null if not used, otherwise an actor
	 * @param director
	 *            - null if not used, otherwise a director
	 * @param genres
	 *            - null if not used, otherwise a list of genres
	 * @param countries
	 *            - null if not used, otherwise a country
	 * **/
	int countMovies(String titleSubStr, int releaseYearMin, int releaseYearMax,
			float rankMin, float rankMax, Actor actor, Director director,
			List<Genre> geners, Country countries) throws DB_Error;

	/**
	 * returns set of movies that match wanted query orderd by title
	 * 
	 * @param titleSubStr
	 *            - null if not used, otherwise some string
	 * @param releaseYearMin
	 *            - -1 if not used, otherwise a year
	 * @param releaseYearMax
	 *            - -1 if not used, otherwise a year
	 * @param rankMin
	 *            - -1.0F if not used, otherwise a rank
	 * @param rankMax
	 *            -1.0F if not used, otherwise a rank
	 * @param actor
	 *            - null if not used, otherwise an actor
	 * @param director
	 *            - null if not used, otherwise a director
	 * @param genres
	 *            - null if not used, otherwise a list of genres
	 * @param countries
	 *            - null if not used, otherwise a country
	 * **/
	List<Movie> getMovies(String titleSubStr, int releaseYearMin,
			int releaseYearMax, float rankMin, float rankMax, Actor actor,
			Director director, List<Genre> geners, Country countries, int from,
			int to) throws DB_Error;

	/**
	 * returns set of movie's directors
	 * 
	 * @param movie
	 * */
	List<Director> getMovieDirectors(Movie movie, int from, int to)
			throws DB_Error;

	/**
	 * returns set of movie's actors
	 * 
	 * @param movie
	 * */
	List<Actor> getMovieActors(Movie movie, int from, int to) throws DB_Error;

	/**
	 * returns set of movie's genres
	 * 
	 * @param movie
	 * */
	List<Genre> getMovieGenres(Movie movie, int from, int to) throws DB_Error;

	/**
	 * returns set of movie's countries
	 * 
	 * @param movie
	 * */
	List<Country> getMovieCountries(Movie movie, int from, int to)
			throws DB_Error;

	/**
	 * performs a specific action on movie's entity
	 * 
	 * @param movie
	 * @param entity
	 *            - the kind of entity
	 * @param entityId
	 * 
	 */
	void actionEntityFromMovie(ACTION action, Movie movie, ENTITIES entity,
			int entityId) throws DB_Error;

	// Manage Question Interface

	/**
	 * returns number of answers that match the question (pattern + entityIdQ
	 * describes a question)
	 * 
	 * @param pattern
	 * @param entityIdQ
	 * **/
	int countAnswers(PATTERN pattern, int entityIdQ) throws DB_Error;

	/**
	 * Inserts a question to the data base
	 * 
	 * @param pattern
	 *            - a question pattern
	 * @param entityIdQ
	 *            - the entity id that completes the question
	 */
	void createQuestion(PATTERN pattern, int entityIdQ, int entityIdA, int level)
			throws DB_Error;

	/**
	 * return set of right answers (answer kind is actor) for a question -
	 * 
	 * @param - pattern
	 * @param entityIdQ
	 *            - the entity id of the question selected
	 */
	List<Actor> getAnswersActors(PATTERN pattern, int entityIdQ, int from,
			int to) throws DB_Error;

	/**
	 * return set of right answers (answer kind is movie) for a question -
	 * 
	 * @param entityIdQ
	 *            - the entity id of the question selected
	 * @param pattern
	 */
	List<Movie> getAnswersMovies(PATTERN pattern, int entityIdQ, int from,
			int to) throws DB_Error;

	/**
	 * return set of right answers (answer kind is genre) for a question -
	 * 
	 * @param entityIdQ
	 *            - the entity id of the question selected
	 * @param pattern
	 */
	List<Genre> getAnswersGenres(PATTERN pattern, int entityIdQ, int from,
			int to) throws DB_Error;

	/**
	 * search a question in a pattern on success will return a list of
	 * DBQuestion
	 * 
	 * @param titleSubStr
	 *            - substring of the parameter that always changes
	 */
	List<DBQuestion> getQuestions(PATTERN pattern, String titleSubStr,
			int from, int to) throws DB_Error;

	/**
	 * search a question in a pattern on success will return a list of
	 * DBQuestion
	 * 
	 * @param titleSubStr1
	 *            - substring of the first parameter in a question
	 * @param titleSubStr2
	 *            - substring of the second parameter in a question
	 */
	List<DBQuestion> getQuestions(PATTERN pattern, String titleSubStr1,
			String titleSubStr2, int from, int to) throws DB_Error;

	/**
	 * returns number of questions about a movie that match the pattern
	 * 
	 * @param pattern
	 * @param titleSubStr
	 * **/
	int countQuestionMovie(PATTERN pattern, String titleSubStr) throws DB_Error;

	/**
	 * returns number of questions about a person that match the pattern
	 * 
	 * @param pattern
	 * @param firstNameSubStr
	 * @param lastNameSubStr
	 * **/
	int countQuestioPerson(PATTERN pattern, String firstNameSubStr,
			String lastNameSubStr) throws DB_Error;

	/**
	 * returns number of questions about a year that match the pattern
	 * 
	 * @param pattern
	 * @param minYear
	 * @param maxYear
	 * **/
	int countQuestioYear(PATTERN pattern, int minYear, int maxYear)
			throws DB_Error;

	/**
	 * Delete a question
	 * 
	 * @param pattern
	 *            - a question pattern
	 * @param questionId
	 *            - the question id that should be deleted
	 */
	void deleteQuestion(PATTERN pattern, int questionId) throws DB_Error;

	/**
	 * generates new questions int he data base
	 * 
	 * @param questionNum
	 *            - the number of questions to generate for each pattern and
	 *            level
	 */
	void generateQuestions(int questionNum) throws DB_Error;

	//imports and updates
	
	/**
	 * sets all the DB Files paths.
	 */
	void setDBFilesPaths(String moviesFilePath, String ratingsFilePath,
			String countriesFilePath, String genresFilePath,
			String actorsFilePath, String actressesFilePath,
			String directorsFilePath);

	/**
	 * delete all the data from DB tables, convert the tables to MyISAM, import
	 * the data into the DB, and convert the tables back to InnoDB
	 * 
	 * @throws DB_Error
	 *             if an SQL error occurred
	 */
	void importToDB() throws DB_Error;

	/**
	 * convert the tables to MyISAM, update the data into the DB, and convert
	 * the tables back to InnoDB
	 * 
	 * @throws DB_Error
	 *             if an SQL error occurred
	 */
	void largeUpdateDB() throws DB_Error;

	/**
	 * update the data into the DB (without converting the tables type). this
	 * function will be used when there is a small amount of data to update
	 * (less the 10k)
	 * 
	 * @throws DB_Error
	 *             if an SQL error occurred
	 */
	void smallUpdateDB() throws DB_Error;

	/**
	 * this function should be call after and import or an update . it will
	 * clear all parser params.
	 */
	void clearParserParams();

}